package de.ff7rl.core.tools;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.LayoutManager;

public class VerticalLayout implements LayoutManager {

  public final static int CENTER = 0;
  public final static int RIGHT = 1;
  public final static int LEFT = 2;
  public final static int BOTH = 3;
  public final static int TOP = 1;
  public final static int BOTTOM = 2;

  private final int vgap;
  private final int alignment;
  private final int anchor;

  public VerticalLayout() {
    this(5, CENTER, TOP);
  }

  public VerticalLayout(final int theVgap) {
    this(theVgap, CENTER, TOP);
  }

  public VerticalLayout(final int theVgap, final int theAlignment) {
    this(theVgap, theAlignment, TOP);
  }

  public VerticalLayout(final int thVgap, final int theAlignment, final int theAanchor) {
    vgap = thVgap;
    alignment = theAlignment;
    anchor = theAanchor;
  }

  @Override
  public void addLayoutComponent(final String name, final Component comp) {
  }

  @Override
  public void layoutContainer(final Container parent) {
    final Insets insets = parent.getInsets();
    synchronized (parent.getTreeLock()) {
      final int n = parent.getComponentCount();
      final Dimension pd = parent.getSize();
      int y = 0;
      // work out the total size
      for (int i = 0; i < n; i++) {
        final Component c = parent.getComponent(i);
        final Dimension d = c.getPreferredSize();
        y += d.height + vgap;
      }
      y -= vgap; // otherwise there's a vgap too many
      // Work out the anchor paint
      if (anchor == TOP) {
        y = insets.top;
      } else if (anchor == CENTER) {
        y = (pd.height - y) / 2;
      } else {
        y = pd.height - y - insets.bottom;
      }
      // do layout
      for (int i = 0; i < n; i++) {
        final Component c = parent.getComponent(i);
        final Dimension d = c.getPreferredSize();
        int x = insets.left;
        int wid = d.width;
        if (alignment == CENTER) {
          x = (pd.width - d.width) / 2;
        } else if (alignment == RIGHT) {
          x = pd.width - d.width - insets.right;
        } else if (alignment == BOTH) {
          wid = pd.width - insets.left - insets.right;
        }
        c.setBounds(x, y, wid, d.height);
        y += d.height + vgap;
      }
    }
  }

  @Override
  public Dimension minimumLayoutSize(final Container parent) {
    return layoutSize(parent, false);
  }

  @Override
  public Dimension preferredLayoutSize(final Container parent) {
    return layoutSize(parent, false);
  }

  @Override
  public void removeLayoutComponent(final Component comp) {
  }

  @Override
  public String toString() {
    return getClass().getName() + "[vgap=" + vgap + " align=" + alignment + " anchor=" + anchor + "]";
  }

  private Dimension layoutSize(final Container parent, final boolean minimum) {
    final Dimension dim = new Dimension(0, 0);
    Dimension d;
    synchronized (parent.getTreeLock()) {
      final int n = parent.getComponentCount();
      for (int i = 0; i < n; i++) {
        final Component c = parent.getComponent(i);
        if (c.isVisible()) {
          d = minimum ? c.getMinimumSize() : c.getPreferredSize();
          dim.width = Math.max(dim.width, d.width);
          dim.height += d.height;
          if (i > 0) {
            dim.height += vgap;
          }
        }
      }
    }
    final Insets insets = parent.getInsets();
    dim.width += insets.left + insets.right;
    dim.height += insets.top + insets.bottom + vgap + vgap;
    return dim;
  }

}
